/*
    This file is part of p4f
    Copyright (C) 2009  Sebastian Fernandez

    p4f is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as 
    published by the Free Software Foundation, either version 3 of the 
    License, or (at your option) any later version.

    p4f is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
*/

#include <parser.h>
#include <string.h>

Parser::Parser(char *init, int length)
{
	this->sep = NULL;
	
	this->length = length;
	this->pos = 0;
	
	this->data = (char *)malloc(length+1);
	this->set_separator("\n\r\t ");
	memcpy(this->data, init, length);

}

Parser::~Parser()
{
	if(this->data != NULL)
		free(this->data);
	if(this->sep != NULL)
		free(this->sep);
}

void Parser::set_separator(char *separator)
{
	if(sep == NULL)
		this->sep = (char *)malloc(strlen(separator)+1);
	else{
		free(this->sep);
		this->sep = (char *)malloc(strlen(separator)+1);
	}
	
	memcpy(this->sep, separator, strlen(separator));
}

int Parser::find_word(char *word)
{
	int local, i, len;
	
	len = strlen(word);
	
	if(len > this->length)
		return -1;
	for(i=0; i < this->length - len; i++){
		if(memcmp(&this->data[i], word, len) == 0){
			this->pos = i;
			return i;
		}
	}
	return -1;
}

bool Parser::goto_pos(int pos)
{
	if(pos > length)
		return false;
	this->pos = pos;
}

bool Parser::goto_newline()
{
	for(; this->pos < this->length; this->pos++){
		if(this->data[this->pos]=='\n'){
			this->pos++;
			return true;
		}
	}
	return false;
}

char *Parser::get_next()
{
	int i, j, pos1, pos2=0;
	char *tmp;

	//Get to a valid word
	for(i=this->pos; i < this->length; i++){
		if(is_inside(this->data[i], this->sep)==true){
			pos1 = i;
			break;
		}
	}
	
	for(; i < this->length; i++){
		if(is_inside(this->data[i], this->sep)==false){
			pos1 = i;
			break;
		}
	}

	for(; i < this->length; i++){
		if(is_inside(this->data[i], this->sep)==true){
			pos2 = i;
			break;
		}
	}
	if(pos2 == 0)
		pos2 = i;
	if(pos1 < this->length){
		tmp = (char *)malloc(pos2-pos1+3);
		memcpy(tmp, &this->data[pos1],pos2-pos1);
		tmp[pos2+1] = '\0';
		return tmp;
	}
	return NULL;
}

bool Parser::is_inside(char ch, char *text)
{
	int i, len;
	len = strlen(text);
	for(i=0; i < len; i++){
		if( text[i] == ch ){
			return true;
		}
	}
	return false;
}
